from flask import Flask, jsonify, request, abort, g
from models import db, User, Video, Follow, Ranking
from datetime import datetime
from sqlalchemy import exc
import logging


app = Flask(__name__)

# 记录错误和请求信息
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 配置SQLite数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///minivideo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化数据库
db.init_app(app)


class APIError(Exception):
    """自定义API异常"""
    def __init__(self, message, status_code=400):
        self.message = message
        self.status_code = status_code

    def to_dict(self):
        return {'message': self.message}

@app.errorhandler(APIError)
def handle_error(e):
    """处理API异常"""
    return jsonify(e.to_dict()), e.status_code


@app.before_request
def log_request_start():
    import time
    g.start_time = time.time()

@app.after_request
def log_request_end(response):
    import time
    if request.path != '/health':  # 排除健康检查的日志
        duration = round(time.time() - g.start_time, 2)
        logger.info(f"{request.method} {request.path} - {response.status_code} ({duration}s)")
    return response


@app.route('/rankings', methods=['POST'])
def create_ranking():
    """创建新榜单"""
    data = request.json
    
    # 基础数据校验
    if not data.get('rank_type') or not data.get('content'):
        raise APIError('缺少必要参数', 400)
    
    try:
        # 检查榜单类型是否重复
        if Ranking.query.filter_by(rank_type=data['rank_type']).first():
            raise APIError('该榜单类型已存在', 409)
            
        # 创建新榜单记录
        new_ranking = Ranking(
            rank_type=data['rank_type'],
            content=data['content'],
            created_at=datetime()
        )
        db.session.add(new_ranking)
        db.session.commit()
        
        return jsonify({'id': new_ranking.id}), 201
        
    except exc.IntegrityError:
        raise APIError('数据库错误，请检查数据有效性', 500)

@app.route('/videos/<int:video_id>/views', methods=['POST'])
def increment_views(video_id):
    """增加视频观看次数"""
    video = Video.query.get(video_id)
    if not video:
        raise APIError('视频不存在', 404)
    
    try:
        # 通过SQL原子操作增加计数
        video.views += 1
        db.session.commit()
        return jsonify({'views': video.views}), 200
    except:
        db.session.rollback()
        raise APIError('更新失败，请重试', 500)


@app.route('/health')
def health_check():
    """健康检查"""
    try:
        db.session.execute('SELECT 1')  # 数据库连接测试
        return jsonify({'status': 'healthy'})
    except:
        return jsonify({'status': 'unhealthy'}), 500


if __name__ == '__main__':
    with app.app_context():
        db.create_all()  # 首次运行时创建数据库表
    app.run(host='0.0.0.0', port=5000)